package org.jvm.nativemethod.methods.java.lang;

import org.jvm.nativemethod.NativeMethodRegister;
import org.jvm.rtda.Object;
import org.jvm.rtda.heap.Klass;
import org.jvm.rtda.heap.classLoader.*;
import org.jvm.rtda.thread.Frame;

/**
 * 本地方法
 *
 * @author 海燕
 * @date 2023/2/19
 */
public class ThreadNativeMethod extends NativeMethodRegister {

    public static void init() throws NoSuchMethodException {
        register("java/lang/Thread", "currentThread", "()Ljava/lang/Thread;", ThreadNativeMethod.class.getDeclaredMethod("currentThread", Frame.class));
        register("java/lang/Thread", "setPriority0", "(I)V", ThreadNativeMethod.class.getDeclaredMethod("setPriority0", Frame.class));
        register("java/lang/Thread", "isAlive", "()Z", ThreadNativeMethod.class.getDeclaredMethod("isAlive", Frame.class));
        register("java/lang/Thread", "start0", "()V", ThreadNativeMethod.class.getDeclaredMethod("start0", Frame.class));
        register("java/lang/Thread", "isInterrupted", "(Z)Z", ThreadNativeMethod.class.getDeclaredMethod("isInterrupted", Frame.class));
    }

    /**
     * TODO 获取当前线程，当前方法实现并不正确
     * 每个Thread都应持有一个java/lang/Thread的实例引用，这里实际应当返回这个实例引用
     *
     * @param frame
     */
    public static void currentThread(Frame frame) {
        //jThread := frame.Thread().JThread()
        BootKlassLoader bootKlassLoader = KlassLoaderRegister.getBootKlassLoader();
        Klass threadClass = bootKlassLoader.loadKlass("java/lang/Thread");
        Object jThread = threadClass.newObject();

        Klass threadGroupClass = bootKlassLoader.loadKlass("java/lang/ThreadGroup");
        Object jGroup = threadGroupClass.newObject();

        jThread.setRefVar("group", "Ljava/lang/ThreadGroup;", jGroup);
        jThread.setIntVar("priority", "I", 1);

        frame.getOperandStack().pushRef(jThread);
    }

    /**
     * TODO 设置线程优先级
     *
     * @param frame
     */
    public static void setPriority0(Frame frame) {

    }

    public static void isAlive(Frame frame) {
        frame.getOperandStack().pushBoolean(false);
    }

    public static void start0(Frame frame) {

    }

    public static void isInterrupted(Frame frame) {
        frame.getOperandStack().pushBoolean(false);
    }

}
